// FileSystem/image-processor.js
import multer from "multer";
import path from "path";
import FileStreamManager from "./file-stream-manager.js";

// 创建文件流管理器实例
const fileManager = new FileStreamManager({
  baseDir: "uploads", // 设置基础目录为uploads
});

/** cb(null, finalFilename); 参数(错误处理-会中断文件上传，最终文件名) */
// 配置multer存储
const createStorage = (options = {}) => {
  const { baseDir = "uploads", filenameGenerator = null } = options;
  const fileManager = new FileStreamManager({ baseDir });

  return multer.diskStorage({
    // 确保上传目录存在
    destination: async (req, file, cb) => {
      try {
        await fileManager.ensureDirectoryExists(fileManager.baseDir);
        cb(null, fileManager.baseDir);
      } catch (err) {
        cb(new Error("服务器存储不可用"));
      }
    },
    filename: async (req, file, cb) => {
      try {
        console.log(file);
        // 中文乱码处理，并存储到 req.file
        const originalname = sanitizeFilename(file.originalname);
        file.originalname = originalname;
        // 获取文件扩展名
        const ext = path.extname(originalname).toLowerCase();
        // 如果有自定义文件名生成器，使用自定义名
        if (filenameGenerator) {
          const customName = await filenameGenerator(req, file, ext);
          cb(null, customName);
          return;
        }
        // 随机生成新文件名（带时间戳和随机数，防止冲突）
        const basename = path
          .basename(originalname, ext)
          .replace(/\s+/g, "_")
          .slice(0, 100); // 限制长度
        const finalFilename = `${basename}_${Date.now()}_${Math.random()
          .toString(36)
          .slice(2, 8)}${ext}`;
        // 使用最终文件名
        cb(null, finalFilename);
      } catch (err) {
        console.error("文件名处理失败，使用随机名称:", err);
        cb(null, `file_${Date.now()}.dat`);
      }
    },
  });
};

// 默认上传配置
export const upload = multer({
  storage: createStorage(),
  fileFilter: (req, file, cb) => {
    try {
      // MIME类型检查
      const allowedTypes = [
        "image/jpeg",
        "image/png",
        "image/gif",
        "image/svg+xml",
      ];
      const isValidType = allowedTypes.includes(file.mimetype);

      // 扩展名双重验证
      const ext = path.extname(file.originalname).toLowerCase();
      const isValidExt = [".jpg", ".jpeg", ".png", ".gif", ".svg"].includes(
        ext
      );

      if (isValidType && isValidExt) {
        cb(null, true);
      } else {
        cb(
          new Error(`文件类型[${file.mimetype}]或扩展名[${ext}]不被允许`),
          false
        );
      }
    } catch (err) {
      cb(new Error("文件验证失败"), false);
    }
  },
  limits: {
    fileSize: 1024 * 1024 * 5, // 5MB限制
    files: 5, // 最多5个文件
    fields: 10, // 最多10个字段
  },
});

// 创建自定义上传中间件
export const createUploader = (options = {}) => {
  const {
    baseDir = "uploads",
    filenameGenerator = null,
    ...multerOptions
  } = options;

  return multer({
    storage: createStorage({ baseDir, filenameGenerator }),
    fileFilter: upload.fileFilter,
    limits: upload.limits,
    ...multerOptions,
  });
};
// 解码文件名
export const decodeFilename = (filename) => {
  try {
    return decodeURIComponent(filename);
  } catch (e) {
    console.warn("文件名解码失败:", filename);
    return filename;
  }
};

// 解码和清理文件名
export const sanitizeFilename = (filename) => {
  try {
    // 先尝试从 latin1 转 utf8（处理 Node.js 默认的文件名编码问题）
    let decoded = Buffer.from(filename, "latin1").toString("utf8");
    // 处理可能的 URI 编码（如前端 encodeURIComponent 过的文件名）
    if (decoded.includes("%")) {
      while (decoded !== decodeURIComponent(decoded)) {
        decoded = decodeURIComponent(decoded);
      }
    }
    // 移除非法字符（安全防护）
    return decoded
      .replace(/[/\\?*:|"<>]/g, "") // 移除非法文件系统字符
      .replace(/(\.\.\/|\.\/)/g, "") // 防止路径遍历攻击
      .trim();
  } catch (e) {
    console.warn(
      "文件名解码失败，使用原始名称（已过滤非法字符）:",
      filename,
      e
    );
    return filename.replace(/[/\\?*:|"<>]/g, "").trim(); // 失败时仍过滤危险字符
  }
};

// 文件URL获取（支持CDN）
export const getFileUrl = (filepath, options = {}) => {
  const { cdnBase = "" } = options;
  // const FilePath = sanitizeFilename(filepath);
  // const decodedFilepath = decodeFilename(filepath);
  return `${cdnBase}${filepath.replace(/\\/g, "/")}`;
};

// 文件删除（使用FileStreamManager）
export const deleteFile = async (filepath) => {
  try {
    // 标准化路径 - 替换所有反斜杠为正斜杠
    const normalizedPath = filepath.replace(/\\/g, "/");

    // 移除开头的uploads/（如果存在）
    const relativePath = normalizedPath.replace(/^uploads\//, "");
    await fileManager.delete(relativePath);
    console.log(`文件删除成功: ${filepath}`);
    return true;
  } catch (err) {
    if (err.code !== "ENOENT") {
      console.error(`文件删除失败: ${filepath}`, err);
    }
    return false;
  }
};
